# -*- coding: utf-8 -*-
import re
import sys
import socket
import os
import io

import urllib2
PATH_BEAUTIFULSOUP = "./BeautifulSoup-3.2.1/"
if not PATH_BEAUTIFULSOUP in sys.path:
    sys.path.append(PATH_BEAUTIFULSOUP)
from BeautifulSoup import BeautifulSoup



class Httper:

    CR = '\r'
    LF = '\n'
    CRLF = CR+LF

    requeset_method = ['GET','/','HTTP/1.1']

    header2 = {
        'REQUEST_METHOD': 'POST /focus/WPEDWA1102.do HTTP/1.1',
        'Accept':'*/*',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-CA;q=0.6,en;q=0.4,zh-TW;q=0.2',
        'Content-Type': 'text/html; charset=utf-8',
        'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
        'Host': '',
        'Connection': 'Keep-Alive',
        'Cache-Control': 'no-cache'
    }
    header = {
        'REQUEST_METHOD': 'POST /focus/WPEDWA1102.do HTTP/1.1',
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8; InfoPath.2; Tablet PC 2.0)',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Host': '',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-CA;q=0.6,en;q=0.4,zh-TW;q=0.2',
        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
        'Connection': 'Keep-Alive',
        'Cache-Control': 'no-cache',
    }
    str_headers = ''
    str_fields = ''
    host = ''

    ip = ''
    port = 80

    cookies = []

    sock = None

    log_file_full_name = ''

    url = ''


    response_body = ''

    freeze_cookie = False

    p_f_cookie = ''

    def __init__( self, fpath='../log.txt', fcookie='../cookie' ):
        self.log_file_full_name = fpath
        self.f_log = open(self.log_file_full_name, 'wb')

        self.p_f_cookie = fcookie

        if not os.path.isfile(self.p_f_cookie):
            f = open(self.p_f_cookie, 'wb')
            f.close()

        f_cookie = io.open(self.p_f_cookie, 'rt', newline='')
        self.header['Cookie'] = f_cookie.readline().strip('\r').strip('\n')
        self.header2['Cookie'] = f_cookie.readline().strip('\r').strip('\n')
        f_cookie.close()

    def set_cookie(self, header):

        if self.freeze_cookie:
            return

        p = re.compile(r'Set-Cookie: (.+)')
        self.cookies = p.findall(header)

        new_c = []
        [ new_c.extend( c.split(';')  )for c in self.cookies]




        self.cookies = []
        [ self.cookies.append( c.strip(' ').strip('\r').strip('\n')  )for c in new_c]

        i = 0
        while i < len( self. cookies):
            p = re.compile(r'^expires|path|Path')
            if p.match(self.cookies[i]):
                del self. cookies[i]
                i = 0
            else:
                i+=1

        self.cookies = {}.fromkeys(list(self.cookies)).keys()


        if self.header.has_key('Cookie'):
            self.header.pop('Cookie')
        if self.header2.has_key('Cookie'):
            self.header2.pop('Cookie')

        if self.cookies:
            self.header['Cookie'] = '; '.join(self.cookies) +';' #+ ' ; AAS_SessionID=P2X_rWnubMcmHmEVY0gVJUo;'
            self.header2['Cookie'] = '; '.join(self.cookies) +';' #+ ' ; AAS_SessionID=P2X_rWnubMcmHmEVY0gVJUo;'

        # self.str_headers = self.generate_header(self.header);

        if self.freeze_cookie == True:
            f_cookie = open(self.p_f_cookie, 'wb')
            f_cookie.write( self.header['Cookie']+self.CRLF+self.header2['Cookie']  )
            print "wrote cookie"

    def generate_header(self,headers):
        lst = []
        for key,value in headers.items():
            if key == 'REQUEST_METHOD':
                if value:
                    lst.append(value)
            elif len(value) > 0:
                lst.append(key +': '+ value)

            self.str_headers = '\r\n'.join(lst)
        return self.str_headers


    def generate_post_data(self,fields,dourlencode=True):
        if type(fields) != str:
            lst = []
            for i in fields:
                val = dourlencode and urllib2.quote(fields[i]) or fields[i]
                lst.append(i +'='+    val  )
            self.str_fields = '&'.join(lst)
        else:
            self.str_fields = fields
        return self.str_fields

    def send_request(self,url,fields=None,dourlencode=True):

        p = re.compile(r'^\<\?xml')

        if type(fields) == str and p.match(fields):
            header = self.header2
        else:
            header = self.header


        self.str_fields = ''
        if header.has_key('Content-Length'):
            header.pop('Content-Length')
        self.requeset_method[0] = 'GET'

        proto, rest = urllib2.splittype(url)  
        self.host, rest = urllib2.splithost(rest)  
        self.host, self.port = urllib2.splitport(self.host) 
        header['Host'] = self.host 

        if self.port is None:
            self.port = 80
        self.ip = socket.getaddrinfo(self.host,None)[0][4][0]

        p = re.compile(r'^GET|POST')

        if type(fields) == str and p.match(fields):
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
            self.sock.connect((self.ip,self.port)) 
            self.sock.send(fields)  
            self.log('Send:'+ self.CRLF +fields+ self.CRLF,0 )
            self.receive_response()
            print "OK"
            return


        if fields and type(fields) != str and type(fields) != unicode:
            self.requeset_method[0] = 'POST'
            self.generate_post_data(fields,dourlencode)
            header['Content-Length'] = str(len(self.str_fields))
        elif fields:
            self.requeset_method[0] = 'POST'
            self.str_fields = fields + self.CRLF
            header['Content-Length'] = str(len(self.str_fields))


        self.requeset_method[1] = (rest !='' and rest or '/')

        header['REQUEST_METHOD'] = ( self.requeset_method and ' '.join(self.requeset_method) or '')
        header['REQUEST_METHOD'] = ''
        method = ( self.requeset_method and ' '.join(self.requeset_method) or '')

        if self.url:
            header['Referer'] = self.url#LawsonEntity.URL_DOSEARCH#self.url

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        self.sock.connect((self.ip,self.port)) 

        request_text = method + self.CRLF + self.generate_header(header) + (self.CRLF*2) +self.str_fields #+ '&TimeSeriesFrom=20140601&'+'TimeSeriesTo=20140601'

        self.url = url

        self.sock.send(request_text)  

        self.log('Send:'+ self.CRLF +request_text+ self.CRLF,0 )
        self.receive_response()

    def receive_response(self):
        self.response_body = ''
        rstr = self.sock.recv(1024)
        self.set_cookie(rstr)
        self.response_body+=rstr
        self.log('\r\nRECEIVED:\r\n'+rstr,0)
        while rstr:
            rstr = self.sock.recv(2048)
            self.log(rstr,0)
            self.response_body+=rstr
        self.sock.close()

    def close(self):
        self.f_log.close()

    def log(self,msg,tofile=-1):
        if tofile<=0:
            print msg
        if tofile>=0:
            self.f_log.write(msg)
        pass



if __name__ == '__main__':

    httper1 = Httper()
    httper1.send_request('https://supplierweb.carrefour.com.cn/includes/image.jsp')
    httper1.receive_response()
    sys.exit(1)

    PATH_LIB = "./"
    if not PATH_LIB in sys.path:
        sys.path.append(PATH_LIB)
    from LawsonEntity import LawsonEntity
    httper = Httper()
    # 1. Login
    #httper.send_request('http://webmenu.lawson.co.jp/')
    #httper.send_request('http://webmenu.lawson.co.jp/WebMenuOU/dou012/')
    httper.send_request(LawsonEntity.URL_LOGIN, LawsonEntity.POST_DATA_LOGIN)

    # 2. Open Page & Get Cookie
    httper.send_request(LawsonEntity.URL_DOSEARCH)



    # 3. Get Data Report
    httper.freeze_cookie = True
    step = LawsonEntity.Steps[len(LawsonEntity.Steps)-2]
    httper.send_request(step[0], step[1], False)


    # httper.send_request(LawsonEntity.URL_DOSEARCH, LawsonEntity.POST_DATA_DOSEARCH, False)
    # httper.send_request(LawsonEntity.URL_DOSEARCH, LawsonEntity.POST_DATA_DOSEARCH, False)
    httper.send_request(LawsonEntity.URL_DOSEARCH1, LawsonEntity.POST_DATA_DOSEARCH, False)

    httper.close()

    # document.forms[0].dispatchAction.value = 'doSearch';
    # document.forms[0].action = 'WPEDWA1101.do';
    # document.forms[0].submit();